package org.springside.modules.security.springsecurity;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterSecurityInterceptor;
import org.springframework.security.userdetails.User;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springside.modules.utils.SpringContextUtil;

/**
 * SpringSecurity的工具类.
 * 
 * @author calvin
 */
public class SpringSecurityUtils {

	/**
	 * 取得当前用户的登录名,如果当前用户未登录则返回null.
	 */
	public static String getCurrentUserName() {
		Authentication auth = SecurityContextHolder.getContext()
				.getAuthentication();
		if (auth == null)
			return null;

		return auth.getName();
	}

	/**
	 * 取得当前用户,返回值为SpringSecurity的User类及其子类, 如果当前用户未登录则返回null.
	 */
	@SuppressWarnings("unchecked")
	public static <T extends User> T getCurrentUser() {
		Object principal = SecurityContextHolder.getContext()
				.getAuthentication().getPrincipal();

		if (principal == null)
			return null;
		// add by quanxiwei 如果是匿名用户 principal不是一个User类，而是一个String。需要特殊处理
		if (principal instanceof String) {
			T newPrincipal = (T) new User((String) principal, null, true, true,
					true, true, null);
			return newPrincipal;
		}

		return (T) principal;
	}

	public static GrantedAuthority[] getCurrentUserAuthorities() {
		return SecurityContextHolder.getContext().getAuthentication()
				.getAuthorities();
	}

	/**
	 * 刷新内存中的资源，当添加资源后，调用该方法可使资源立即生效哦
	 * 
	 * @param sc 类型javax.servlet.ServletContext 可以通过session获取
	 * @throws Exception
	 */
	public static void updateResource(ServletContext sc) throws Exception{

		ApplicationContext ctx = WebApplicationContextUtils
				.getWebApplicationContext(sc);

		FactoryBean factoryBean = (FactoryBean) ctx
				.getBean("&databaseDefinitionSource");
		FilterInvocationDefinitionSource fids = (FilterInvocationDefinitionSource) factoryBean
				.getObject();
		FilterSecurityInterceptor filter = (FilterSecurityInterceptor) ctx
				.getBean("filterSecurityInterceptor");
		filter.setObjectDefinitionSource(fids);

	}
}
